import { getProp, isArray } from '@/components/cms/utils'
import { Select, Input, type SelectProps } from 'ant-design-vue'
import { defineComponent, nextTick, onMounted, reactive, watch, type PropType } from 'vue'
import { formState } from '../mixins/useState'
import type { JsonSchema, Slots, DefaultOptionType } from '../types'

export default defineComponent({
  inheritAttrs: true,
  emits: ['valueChange'],
  props: {
    schema: {
      type: Object as PropType<JsonSchema>,
      default: () => ({})
    },
    slots: {
      type: Object as PropType<Slots>,
      default: () => undefined
    }
  },
  setup(props, ctx) {
    interface IProps extends SelectProps {
      disabledSpacing?: boolean
      disabledLineHeight?: boolean
    }
    const attrs = { placeholder: '请选择', ...props.schema.props } as IProps
    if (attrs.disabledSpacing === undefined) {
      attrs.disabledSpacing = true
    }
    if (attrs.disabledLineHeight === undefined) {
      attrs.disabledLineHeight = true
    }
    interface IState {
      size: number
      letterSpacing: string | number
      lineHeight: string | number
    }

    const state = reactive<IState>({
      size: 14,
      letterSpacing: '自动',
      lineHeight: '自动'
    })

    const handleChange = (key: string) => {
      const fields = props.schema.field
      if (!isArray(fields)) {
        return
      }
      const tempFields = fields as string[]
      const map: {
        [k in string]: () => void
      } = {
        size: () => {
          if (tempFields.length && tempFields[0]) {
            const value = {
              path: tempFields[0],
              value: state.size
            }
            ctx.emit('valueChange', value)
          }
        },
        letterSpacing: () => {
          if (tempFields.length && tempFields[1]) {
            const value = {
              path: tempFields[1],
              value: state.letterSpacing
            }
            ctx.emit('valueChange', value)
          }
        },
        lineHeight: () => {
          if (tempFields.length && tempFields[2]) {
            const value = {
              path: tempFields[2],
              value: state.lineHeight
            }
            ctx.emit('valueChange', value)
          }
        }
      }
      map[key] && map[key]()
    }
    watch(
      () => state.size,
      () => handleChange('size')
    )

    watch(
      () => state.letterSpacing,
      () => handleChange('letterSpacing')
    )

    watch(
      () => state.lineHeight,
      () => handleChange('lineHeight')
    )

    const defaultSize = [10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 42, 48, 72]
    const defaultFontSizeOptions: DefaultOptionType[] = defaultSize.map((s) => ({ value: s, label: `${s}px` }))
    onMounted(() => {
      nextTick(() => {
        const fields = props.schema.field
        if (!isArray(fields)) {
          return
        }
        const tempFields = fields as string[]
        if (tempFields.length && tempFields[0]) {
          const value = getProp(formState.model, tempFields[0] as string).value as number
          state.size = value
        }
        if (tempFields.length && tempFields[1]) {
          const value = getProp(formState.model, tempFields[1] as string).value as number
          state.letterSpacing = value
        }
        if (tempFields.length && tempFields[2]) {
          const value = getProp(formState.model, tempFields[2] as string).value as number
          state.lineHeight = value
        }
      })
    })
    return () => {
      return (
        <div class={`font-field_wrapper ${(props.schema.props as { class?: string })?.class ?? ''}`}>
          <div class="text-center">
            <Select
              {...attrs}
              options={(attrs?.options ?? defaultFontSizeOptions) as DefaultOptionType[]}
              v-model={[state.size, 'value']}
            />
            <span class="text-white text-[10px] block mt-2" style="zoom: 0.85">
              字号
            </span>
          </div>
          <div class="mx-2 text-center" style={{ opacity: attrs.disabledSpacing ? 0.25 : 1 }}>
            <Input disabled={attrs.disabledSpacing} v-model={[state.letterSpacing, 'value']} />
            <span class="text-white text-[10px] block mt-2" style="zoom: 0.85">
              字距
            </span>
          </div>
          <div class="text-center" style={{ opacity: attrs.disabledSpacing ? 0.25 : 1 }}>
            <Input disabled={attrs.disabledLineHeight} v-model={[state.lineHeight, 'value']} />
            <span class="text-white text-[10px] block mt-2" style="zoom: 0.85">
              行高
            </span>
          </div>
        </div>
      )
    }
  }
})
